import { ReactNode, useState, useRef, useEffect } from 'react';
import { createContext } from 'use-context-selector';
import appService from '@/api/services/appService';
import chatService from '@/api/services/chatService';
import { AppListItem } from '@/common';
import { useShareChatStore } from '@/store/shareStore';
import { SocketIOProvider } from '@/hooks/use-socketio';
import { WebSocketProvider } from '@/hooks/use-websocket';
import useEventEmitter, { EventEmitter } from 'ahooks/lib/useEventEmitter';
import { ChatEvent } from '@/types/chat';
interface chatReportItem {
  key: string;
  label: string;
  tooltip: string;
  children: string;
}

type ChatContextType = {
  event$: EventEmitter<ChatEvent> | null;
  isMetaHuman: boolean;
  isMuted: boolean;
  isAudioPlaying: boolean;
  appId: string;
  shareId: string;
  datasetId: string;
  avatarId: string;
  taskId: string;
  chatId: string;
  actId: string;
  isMessageLoading: boolean;
  isClickTriggered: boolean;

  streamUrl: string;
  mhSessionId: string;
  chatReport: chatReportItem[];
  appInfo: AppListItem | null;
  outLinkUid?: string;
  launchMetaHuman: (id: string) => void;
  stopMetaHuman: () => void;
  stopSpeaking: () => void;
  closeConnection: () => void;
  updateChatInfo: (id: string, sid: string, did: string) => void;
  setMhSessionId: (id: string) => void;
  setTaskId: (id: string) => void;
  setStreamUrl: (id: string) => void;
  setIsMetaHuman: (status: boolean) => void;
  setIsAudioPlaying: (status: boolean) => void;
  setIsMuted: (status: boolean) => void;
  setAppInfo: (app: AppListItem) => void;
  setChatId: (id: string) => void;
  setActId: (id: string) => void;
  setIsMessageLoading: (status: boolean) => void;
  setIsClickTriggered: (status: boolean) => void;

  playAudio: () => void;
  setChatReport: (item: chatReportItem[]) => void;
};

export const ChatContext = createContext<ChatContextType>({
  event$: null,
  isMetaHuman: true,
  isMuted: false,
  isAudioPlaying: false,
  appId: '',
  shareId: '',
  datasetId: '',
  avatarId: '',
  taskId: '',
  chatId: '',
  actId: '',
  isMessageLoading: false,
  isClickTriggered: false,
  streamUrl: '',
  mhSessionId: '',
  appInfo: null,
  chatReport: [],

  updateChatInfo: () => {},
  launchMetaHuman: () => {},
  stopMetaHuman: () => {},
  stopSpeaking: () => {},
  closeConnection: () => {},
  setMhSessionId: () => {},
  setIsMetaHuman: () => {},
  setIsMuted: () => {},
  setTaskId: () => {},
  setStreamUrl: () => {},
  setAppInfo: () => {},
  setChatId: () => {},
  setActId: () => {},
  setIsMessageLoading: () => {},
  setIsClickTriggered: () => {},

  playAudio: () => {},
  setIsAudioPlaying: () => {},
  setChatReport: () => {},
});

const ChatContextProvider = ({ children }: { children: ReactNode }) => {
  const event$ = useEventEmitter<ChatEvent>();
  const [chatReport, setChatReport] = useState<chatReportItem[]>([]);
  const [isMetaHuman, setIsMetaHuman] = useState(false);
  const [appId, setAppId] = useState('');
  const [shareId, setShareId] = useState('');
  const [datasetId, setDatasetId] = useState('');
  const [avatarId, setAvatarId] = useState('');
  const [taskId, setTaskId] = useState('');
  const [chatId, setChatId] = useState('');

  const [actId, setActId] = useState('');
  const [isMessageLoading, setIsMessageLoading] = useState(false);
  const [isClickTriggered, setIsClickTriggered] = useState(false);

  const [streamUrl, setStreamUrl] = useState('');
  const [mhSessionId, setMhSessionId] = useState('');

  const [appInfo, setAppInfo] = useState<AppListItem | null>(null);

  const [isAudioPlaying, setIsAudioPlaying] = useState(false);
  const [isAudioStart, setIsAudioStart] = useState(false);
  const [isMuted, setIsMuted] = useState(false);

  const { localUId } = useShareChatStore();
  const outLinkUid: string = localUId;

  const playAudio = () => {
    if (!isAudioStart) {
      const audioElement = document.getElementById('audio') as HTMLAudioElement;
      if (audioElement) {
        audioElement.play();
        setIsAudioStart(true);
      }
    }
  };

  useEffect(() => {
    if (!isMetaHuman) {
      setStreamUrl('');
      setMhSessionId('');
    }
  }, [isMetaHuman]);

  const stopSpeaking = async () => {
    let mhSessionIdInt = parseInt(mhSessionId, 10);

    if (isNaN(mhSessionIdInt)) {
      console.log('mhSessionId:' + mhSessionId);
      return;
    }
    if (!streamUrl) {
      return;
    }

    let origin = new URL(streamUrl).origin;

    // let api = origin + '/human'
    // let api = 'http://172.30.232.99:29444/human'

    const hostname = new URL(origin).hostname;
    const port = new URL(origin).port;
    let api = '';
    if (port) {
      api = '/api/openapi/proxy/' + hostname + ':' + port + '/human';
    } else {
      api = '/api/openapi/proxy/' + hostname + '/human';
    }

    let body = {
      text: '',
      sessionid: mhSessionIdInt,
      interrupt: true,
      type: 'echo',
    };

    if (chatId) {
      body.chatId = chatId;
    }

    fetch(api, {
      body: JSON.stringify(body),
      headers: {
        'Content-Type': 'application/json',
      },
      method: 'POST',
    });
  };

  const closeConnection = async () => {
    setIsAudioStart(false);
    setIsAudioPlaying(false);
    let mhSessionIdInt = parseInt(mhSessionId, 10);

    if (isNaN(mhSessionIdInt)) {
      console.log('mhSessionId:' + mhSessionId);
      return;
    }
    if (!streamUrl) {
      return;
    }

    let origin = new URL(streamUrl).origin;

    // // let api = origin + '/close_connection'
    // let api = 'http://172.30.232.99:29444/close_connection'
    // let api = origin + '/release_session'

    const hostname = new URL(origin).hostname;
    const port = new URL(origin).port;
    let api = '';
    if (port) {
      api = '/api/openapi/proxy/' + hostname + ':' + port + '/close_connection';
    } else {
      api = '/api/openapi/proxy/' + hostname + '/close_connection';
    }
    // let api =  '/api/openapi/proxy/'+ hostname + ':' + port + '/release_session'

    fetch(api, {
      body: JSON.stringify({
        sessionid: mhSessionIdInt,
      }),
      headers: {
        'Content-Type': 'application/json',
      },
      method: 'POST',
    });
  };

  const launchMetaHuman = async (id: string) => {
    try {
      setIsAudioStart(false);
      setIsAudioPlaying(false);

      const appResponse = await appService.appDetail(id);
      let appAvatarId = appResponse.metahuman.avatar_id;

      if (!appAvatarId) {
        throw Error('暂无可用数字人');
      }

      setAvatarId(appAvatarId);
      setStreamUrl('');
      setMhSessionId('');

      const data = await chatService.startMetaHuman(appAvatarId);
      if (data.task_id) {
        setTaskId(data.task_id);
      } else {
        if (data.message) {
          throw Error(data.message);
        }
      }
    } catch (error) {
      throw error;
    }
  };

  const stopMetaHuman = async () => {
    if (taskId) {
      chatService.stopMetahuman(taskId);
    }
  };

  const updateChatInfo = (id: string, sid: string, did: string) => {
    setAppId(id);
    setShareId(sid);
    setDatasetId(did);
  };

  const contextValue: ChatContextType = {
    event$,
    isMetaHuman,
    appId,
    shareId,
    datasetId,
    updateChatInfo,
    avatarId,
    taskId,
    chatId,
    actId,
    isMessageLoading,
    isClickTriggered,
    streamUrl,
    mhSessionId,
    appInfo,
    isMuted,
    isAudioPlaying,
    chatReport,
    outLinkUid,
    launchMetaHuman,
    stopMetaHuman,
    setMhSessionId,
    setIsMetaHuman,
    setTaskId,
    setStreamUrl,
    setAppInfo,
    stopSpeaking,
    closeConnection,
    setChatId,
    setActId,
    setIsMessageLoading,
    setIsClickTriggered,
    playAudio,
    setIsMuted,
    setIsAudioPlaying,
    setChatReport,
  };

  return (
    <ChatContext.Provider value={contextValue}>
      {children}
    </ChatContext.Provider>
  );
};

export default ChatContextProvider;
